// 固定优先级
module fixed_prio_arb(
           input [2: 0] req,
           output reg [2: 0] grant
       );

always@( * )
	begin
		case (1'b1)
			req[0]:
				grant = 3'b001;
			req[1]:
				grant = 3'b010;
			req[2]:
				grant = 3'b100;
		endcase
	end
endmodule


    //参数化仲裁器，请求个数不确定
    module priority_arbiter #(
        parameter req_width = 16
    )(
        input [req_width - 1: 0] req,
        output reg [req_width - 1: 0] grant
    );
// req  011100
// pre  111100
//grant 000100
integer i;
reg [req_width - 1: 0] pre_req;
always@( * )
	begin
		pre_req[0] = req[0];
		grant[0] = req[0];
		for (i = 1;i < req_width;i = i + 1)
			begin
				grant[i] = req[i] & !pre_req[i - 1];
				pre_req[i] = req[i] | pre_req[i - 1];
			end
	end

endmodule


    //更简洁的写法1
    module priority_arbiter1 #(
        parameter req_width = 16
    )(
        input [req_width - 1: 0] req,
        output wire [req_width - 1: 0] grant
    );

// req  010010
// pre  111100
// ~pre 000011
//grant 000010
wire [req_width - 1: 0] pre_req;
assign pre_req[0] = 1'b0;
assign pre_req[req_width - 1: 1] = req[req_width - 2: 0] | pre_req[req_width - 2: 0];
assign grant = req & ~pre_req;

endmodule


    //更简洁的写法2
    module priority_arbiter2 #(
        parameter req_width = 16
    )(
        input [req_width - 1: 0] req,
        output wire [req_width - 1: 0] grant
    );

//req       010010
// req-1    010001
// ~(req-1) 101110
// grant    000010
assign grant = req & (~(req - 1'b1));
endmodule
